package cn.hutool.postfix.generator;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Tuple;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import cn.hutool.postfix.generator.common.Config;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author liuxiongkang
 */
public class RuleOverrides {
    private static final Log LOG = LogFactory.get(RuleOverrides.class);
    private static final Pattern TEMPLATE_NAME = Pattern.compile("\\.([\\w]+)\\s.*");
    private static final Pattern MATCHING_TYPE = Pattern.compile("\\s*([^→]+?)\\s*→.*");

    private RuleOverrides() {
        //do nothing
    }

    /**
     * 单独统计 冲突数
     */
    public static void main(String[] args) {
        overrideRules();
    }

    protected static void overrideRules() {
        List<Tuple> tl = Config.LANG.stream().map(lang -> overrideRules(lang.lang(), FileUtil.file(RuleDocletGenerator.TEMP_PATH + StrPool.C_SLASH + lang.lang()))).collect(Collectors.toList());
        tl.forEach(t -> {
            if (null != t) {
                LOG.info("========== lang:{}, 冲突总数:{} ==========", t.get(0).toString(), t.get(1).toString());
            }
        });
    }

    private static Tuple overrideRules(String lang, File file) {
        if (!file.exists() || !file.isDirectory()) {
            return null;
        }
        Optional<File> all = FileUtil.loopFiles(file, f -> f.getName().contains("hutool-all")).stream().findFirst();
        AtomicInteger count = new AtomicInteger();
        all.ifPresent(f -> {
            List<Tuple> overrideRules = overrideRules(f);
            List<Map.Entry<Tuple, List<Tuple>>> dataList = overrideRules.stream().collect(Collectors.groupingBy(t -> t)).entrySet().stream().filter(e -> e.getValue().size() > 1).collect(Collectors.toList());
            count.set(dataList.size());
            dataList.forEach(e -> LOG.info("lang:{}, 冲突方法名:{}, 冲突参数:{}", lang, e.getKey().get(0), e.getKey().get(1)));
        });
        return new Tuple(lang, count.get());
    }

    private static List<Tuple> overrideRules(File file) {
        if (!file.exists()) {
            return ListUtil.empty();
        }
        List<String> filterLine = geRuleList(file);
        String methodName = "";
        List<Tuple> dataList = new ArrayList<>();
        for (String line : filterLine) {
            Matcher matcherMethodName = TEMPLATE_NAME.matcher(line);
            if (matcherMethodName.matches()) {
                methodName = matcherMethodName.group(1);
                continue;
            }
            matcherMethodName = MATCHING_TYPE.matcher(line);
            if (matcherMethodName.matches()) {
                dataList.add(new Tuple(methodName, matcherMethodName.group(1)));
            }
        }
        return dataList;
    }

    protected static List<String> geRuleList(File file) {
        List<File> files = file.isDirectory() ? FileUtil.loopFiles(file) : ListUtil.toList(file);
        List<String> lines = files.stream().flatMap(file1 -> FileUtil.readUtf8Lines(file1).stream()).collect(Collectors.toList());
        return lines.stream().map(String::trim).filter(CharSequenceUtil::isNotBlank).filter(line -> !line.startsWith("#")).collect(Collectors.toList());
    }
}
